package org.snusmumr.android.media.data;

import java.util.ArrayList;

import org.snusmumr.android.media.Constants;
import org.snusmumr.android.media.R;
import org.snusmumr.android.media.bean.LabelModel;
import org.snusmumr.android.media.data.DatabaseProvider.DatabaseMode;
import org.snusmumr.android.media.util.Bits;
import org.snusmumr.android.media.util.Utils;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.widget.Toast;

public class SaveMediaItemOperation extends DBOperation<Boolean> {
	private static final String TAG = SaveMediaItemOperation.class.getSimpleName();
	
	private MediaItemContainer container;

	public SaveMediaItemOperation(MediaItemContainer container) {
		super(container.getContext());
		this.container = container;
	}
	
	@Override
	protected DatabaseMode getDatabaseMode() {
		return DatabaseMode.Write;
	}

	@Override
	public Boolean execute() {
		String name = container.getName();
		String authorName = container.getAuthorName();
		
		if(Utils.isEmpty(name)) {
			Toast.makeText(getContext(), R.string.msg_err_missing_item_name, Toast.LENGTH_SHORT).show();
			return false;
		}
		
		if(Utils.isEmpty(authorName)) {
			Toast.makeText(getContext(), R.string.msg_err_missing_author_name, Toast.LENGTH_SHORT).show();
			return false;
		}
		
		SQLiteDatabase database = getDatabaseProvider().getDatabase(getDatabaseMode());
		database.beginTransaction();
		boolean res = false;
		try {
			res = saveAuthor(authorName);
			if(res) {
				String labelsMask = saveLabels();
				res = saveItem(name, container.getComment(), labelsMask);
			}
			if(res)
				database.setTransactionSuccessful();
		} finally {
			database.endTransaction();
		}
		
		return res;
	}
	
	private boolean saveAuthor(String authorName) {
		ContentValues values = new ContentValues();
		values.put(MediaColumns.NAME, authorName);
		
		SQLiteDatabase database = getDatabaseProvider().getDatabase(getDatabaseMode());
		Long authorId = container.getAuthorId();
		if(authorId == null) {
			//check if this author is already saved
			Cursor c = database.rawQuery("SELECT _id FROM author WHERE name LIKE '" + authorName.toLowerCase() + "'", null);
			if(c != null && c.moveToFirst()) {
				authorId = c.getLong(0);
			} else {
				authorId = database.insert(Constants.DB_TABLE_AUTHOR, null, values);
				if(authorId == -1L) {
					Log.e(TAG, "ERROR: cannot insert author");
					return false;
				}
			}
			c.close();
			container.setAuthorId(authorId);
		} else {
			database.update(Constants.DB_TABLE_AUTHOR, values, "_id=?", new String[]{authorId.toString()});
		}
		return true;
	}
	
	private String saveLabels() {
		String labelsMask = null;
		ArrayList<LabelModel> labels = container.getLabels();
		int size = labels.size();
		for(int i=0; i<size; i++) {
			LabelModel lm = labels.get(i);
			labelsMask = Bits.setBit(labelsMask, lm.getId().intValue(), true);
		}
		return labelsMask;
	}
	
	private boolean saveItem(String name, String comment, String labelsMask) {
		SQLiteDatabase database = getDatabaseProvider().getDatabase(getDatabaseMode());
		long itemId = container.getItemId();
		
		ContentValues values = new ContentValues();
		values.put(MediaColumns.NAME, name);
		values.put(MediaColumns.CATEGORY_ID, container.getCategoryId());
		values.put(MediaColumns.AUTHOR_ID, container.getAuthorId());
		values.put(MediaColumns.COMMENT, comment);
		values.put(MediaColumns.LABELS_MASK, labelsMask);
		if(itemId == -1L) {
			itemId = database.insert(Constants.DB_TABLE_MEDIA_ITEM, null, values);
			if(itemId == -1L) {
				Log.e(TAG, "ERROR: cannot insert media item");
				return false;
			}
			container.setItemId(itemId);
		} else {
			database.update(Constants.DB_TABLE_MEDIA_ITEM, values, "_id=?", new String[]{String.valueOf(itemId)});
		}
		return true;
	}
	
	public interface MediaItemContainer {
		public Context getContext();
		
		public Long getAuthorId();
		public void setAuthorId(Long authorId);
		
		public long getCategoryId();
		public long getItemId();
		public void setItemId(long itemId);
		
		public ArrayList<LabelModel> getLabels();
		
		public String getAuthorName();
		public String getName();
		public String getComment();
	}

}
